//===============================================
// Pos Norm Tex Tan Shader
// Normal tri
//===============================================

#include "ShaderHelp.fxh"

cbuffer cbPerFrame
{
	float3 gLightPos;
	float4 gLightColor;
	float4 gLightSpec;
	float4 gLightAmbient;
	
	float3 gEyePosW;
};

cbuffer cbPerObject
{
	matrix gWorld : World;
	matrix gWVP : WorldViewProjection;
	matrix gLightWVP : LightWorldViewProj;
	matrix gTexMat;
};

Texture2D diffuseMap;
Texture2D ShadowMap;
Texture2D NormalMap;
Texture2D SpecMap;

SamplerState diffuseSampler
{
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

struct VS_INPUT
{
    float3 Pos          : POSITION;
    float3 Norm			: NORMAL;
    float2 Tex          : TEXCOORD;
    float3 Tan			: TANGENT;
};

struct PS_INPUT
{
    float4 Pos     : SV_POSITION;
    float3 Norm     : TEXCOORD0;
    float4 WorldPos  : TEXCOORD1;
    float2 Tex     : TEXCOORD2;
    float4 projTex : TEXCOORD3;
};


//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT vIn )
{
    PS_INPUT vOut = (PS_INPUT)0;
	
	float4 hPos = float4(vIn.Pos, 1);
	vOut.Pos = mul(hPos, gWVP);
	vOut.WorldPos = mul(hPos, gWorld);
	vOut.Norm  = mul(vIn.Norm, (float3x3)gWorld);
	vOut.Norm = normalize(vOut.Norm);
	vOut.Tex = mul(float4(vIn.Tex, 1.0f, 1.0f), gTexMat).xy;
	
	vOut.projTex = mul(float4(vIn.Pos, 1.0f), gLightWVP);
	
	return vOut;
}
	
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------

float4 PS( PS_INPUT input) : SV_Target
{
	float4 diffuse = diffuseMap.Sample( diffuseSampler, input.Tex );
	
	// Kill transparant pixels
	clip( diffuse.a - 0.15f );
	
	float4 spec = float4(1,1,1,1);
	
	float ShadowFactor = CalcShadowFactor(input.projTex, ShadowMap);
	
	SurfaceInfo v = {input.WorldPos.xyz, input.Norm, diffuse, spec};
	
	Light L;
	L.pos = gLightPos;
	L.dir = -normalize(gLightPos);
	L.ambient = gLightAmbient;
	L.diffuse = gLightColor;
	L.spec = gLightSpec;
	
	float3 litColor = ParallelLightShadow(v, L, gEyePosW, ShadowFactor);
	
	return float4(litColor, 1.0f) ;
	//return float4(ShadowFactor, ShadowFactor, ShadowFactor, 1.0f);
}


//--------------------------------------------------------------------------------------
// Technique
//--------------------------------------------------------------------------------------

RasterizerState EnableCulling
{
    CullMode = Back;
    FrontCounterClockwise = false;
};

DepthStencilState DepthEnabling
{
	DepthEnable = TRUE;
};

BlendState DisableBlend
{
	BlendEnable[0] = FALSE;
};


technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
              
		SetDepthStencilState(DepthEnabling, 0);
		SetBlendState(DisableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
    }
}

